#include "MTMatrix.hpp"
#include "MTExpression.hpp"
#include "MTList.hpp"
#include "Params.h"
#include <string>
#include <iostream>
#include <sstream>

namespace MathematicaTranslator
{
	std::string* MTMatrix::generateCode(CodeGenContext& context)
	{
		std::ostringstream ss;

		ss << " = { ";

		int row_size = atoi(matrix->at(0)->getNumberOfElements()->c_str()); //(*matrix)[0]->listElements->size();

		for (int i =  matrix->size() - 1; i >= 0  ; i-- )
		{
			if(row_size != atoi(matrix->at(i)->getNumberOfElements()->c_str()))
			{
				std::cerr <<"MATRIX IMPROPERLY DEFINED - MISMATCH IN ROWS SIZE" <<std::endl;
				return new std::string("ERROR: MISMATCH IN MATRIX ROWS SIZE");
			}

			for(int j = 0; j < (*matrix)[i]->listElements->size(); j++)
			{
				ss << *(*(*matrix)[i]->listElements)[j]->generateCode(context);
				if (j < (*matrix)[i]->listElements->size() - 1) ss << ", ";
			}
			if(i > 0) ss << ", ";
		}
		ss << "}";

		return new std::string(ss.str());
	}
	std::string* MTMatrix::getType()
	{
		std::string* type = new std::string("");
		
		for(int i = 0; i < matrix->size(); i++)
		{
			for(int j = 0; j < (*matrix)[i]->listElements->size(); j++ )
			{
				std::string* currentType = (*(*matrix)[i]->listElements)[j]->getType();
				if( *currentType == "int" && *type != "float" )
				{
					*type = "int";
				} else if(*currentType == "float")
				{
					*type = "float";
				} else if(*currentType == "double")
				{
					*type = "double";
					break;
				}
			}	
		}
		return type;
	}

	std::string* MTMatrix::getNumberOfElements()
	{
		std::ostringstream ss;
		int numberInRow = atoi(matrix->at(0)->getNumberOfElements()->c_str());
		//ss << matrix->size() *  (*matrix)[0]->listElements->size();
		ss << matrix->size() * numberInRow;
		//std::cout << "================================> " << matrix->size() << "\n";
		//std::cout << "==================================> " << numberInRow << "\n"; 

		return new std::string(ss.str());
	}
	
	int MTMatrix::getClassType(){
		return MATRIX;
	}
}
